SciChart WPF 2D Charts > Axis APIs > Axis Ranging - Clipping VisibleRange
Axis Ranging - Clipping VisibleRange

Clipping the Axis.VisibleRange on Zoom and Pan

Axis.VisibleRangeLimit

Given a chart with data in the range of 0:10, when you zoom to extents, the axis will have a VisibleRange of 0:10. Sometimes this is not desirable, and you want to clip the Axis.VisibleRange inside the data-range. To do this, you can use the Axis.VisibleRangeLimit property.

For example. Given an axis without any limits (AxisBase.VisibleRangeLimit = null). When we perform ZoomExtents on the parent chart, the XAxis gets the visible range (0;10):

Actual XAxis data range = (0:10) ; XAxis.VisibleRangeLimit = null; XAxis.VisibleRange after ZoomExtents = (0:10)

 

After setting XAxis.VisibleRangeLimit = (1:9) and using ZoomExtents we now get an XAxis.VisibleRange = (1:9). In other words, zooming has clipped or limited the VisibleRange to (1:9)

NOTE:  VisibleRangeLimit does not clip data range when VisibleRangeLimit is greater than data range. In this case after ZoomExtents you’ll get the actual data range.

 

  Actual data range = (0:10); XAxis.VisibleRange = (1:9); XAxis.VisibleRange after ZoomExtents = (1:9)

Declaring Axis.VisibleRangeLimit in XAML

Declaring Axis.VisibleRangeLimit
Copy Code
<s:NumericAxis VisibleRangeLimit="0, 100" />

Declaring Axis.VisibleRangeLimit in XAML / MVVM

Declaring Axis.VisibleRangeLimit
Copy Code
<s:NumericAxis VisibleRangeLimit="{Binding XLimit}" />

// Then, in your ViewModel
private IRange _xLimit = new DoubleRange(0, 100);
public IRange XLimit
{
    get { return _xLimit; }
    set
    {
        _xLimit = value;
        OnPropertyChanged(“XLimit”);
    }
}

Declaring Axis.VisibleRangeLimit in Code

Declaring Axis.VisibleRangeLimit
Copy Code
xAxis.VisibleRangeLimit = new DoubleRange(0.0, 100.0);

 

Axis.VisibleRangeLimitMode

Another property which can be used to change how the VisibleRangeLimit works is AxisBase.VisibleRangeLimitMode.

Use this property if you wish to ensure that one side of the chart is always clipped, while the other side is not. For instance:

Axis.VisibleRangeLimitMode
Copy Code
<!-- Ensures VisibleRangeLimit of 0 is applied to the VisibleRange.Min -->
<!-- The VisibleRange.Max is unbounded -->
<s:NumericAxis VisibleRangeLimit="0,0" VisibleRangeLimitMode="Min"/>

Results in a chart that always sets VisibleRange.Min = 0 when you zoom to extents.

NOTE:  VisibleRangeLimit does not clip data range when VisibleRangeLimit is greater than data range. In this case after ZoomExtents you’ll get the actual data range.

Advanced VisibleRange Clipping and Manipulation

Axis.VisibleRangeLimit is a useful API to ensure the axis clips the VisibleRange when zooming to extents. However, it will not stop a user from scrolling outside of that range. To achieve that, you need a small modification:

Clipping Axis.VisibleRange in Code

To clip the VisibleRange and force a certain maximum or minimum, just use the following code:

Clipping Axis.VisibleRange in Code
Copy Code
axis.VisibleRangeChanged += (s, e) =>
{
   // e is VisibleRangeChangedEventArgs
   // Assuming axis is NumericAxis

   if (e.NewVisibleRange != null && e.NewVisibleRange.Min < 0)
   {
      // Force minimum visiblerange to zero always
      ((NumericAxis)sender).VisibleRange = new DoubleRange(0, e.NewVisibleRange.Max);
   }
};

Clipping Axis.VisibleRange with MVVM

The same can be achieved in MVVM by creating a custom behavior.

Clipping Axis.VisibleRange with MVVM
Copy Code
public class AxisClippingBehavior : Behavior<AxisBase>
{
    protected override void OnAttached()
    {
        base.OnAttached();
  
        AssociatedObject.VisibleRangeChanged +=OnVisibleRangeChanged;
    }
  
    protected override void OnDetaching()
    {
        base.OnDetaching();
  
        AssociatedObject.VisibleRangeChanged -= OnVisibleRangeChanged;
    }
  
    private void OnVisibleRangeChanged(object sender, VisibleRangeChangedEventArgs visibleRangeChangedEventArgs)
    {
        var visibleRangeLimit = AssociatedObject.VisibleRangeLimit;
        if (visibleRangeLimit != null)
        {
            var limitMode = AssociatedObject.VisibleRangeLimitMode;
  
            var range = (IRange)AssociatedObject.VisibleRange.Clone();
            range.ClipTo(visibleRangeLimit, limitMode);
  
            AssociatedObject.SetCurrentValue(AxisBase.VisibleRangeProperty, range);
        }
    }
}

The usage in XAML would then be:

Clipping Axis.VisibleRange with MVVM
Copy Code
<s:NumericAxis>
    <i:Interaction.Behaviors>
        <clipAxis:AxisClippingBehavior />
    </i:Interaction.Behaviors>
</s:NumericAxis>

Specifying a Minimum Zoom Level

If you want to constrain zoom depth in your application, the Axis.MinimalZoomConstrain property allows you to constrain changing of axis VisibleRange if its VisibleRange.Diff value is too small. When you use MinimalZoomConstain you define minimal difference between Min and Max of VisibleRange and if this difference < MinimalZoomConstrain then VisibleRange will not change.  

Specifying Minimum Zoom Level on a NumericAxis or LogarithmicNumericAxis

Specifying Minimum Zoom Level on a NumericAxis or LogarithmicNumericAxis
Copy Code
var numericAxis = new NumericAxis();
// Do not allow zooming where VisibleRange.Max-visibleRange.Min
// is less than 1E-3
numericAxis.MinimalZoomConstrain = 1E-3;

Specifying Minimum Zoom Level on a DateTimeAxis or TimeSpanAxis

Specifying Minimum Zoom Level on a DateTimeAxis or TimeSpanAxis
Copy Code
var dateTimeAxis = new DateTimeAxis();
// Do not allow zooming where VisibleRange.Max-visibleRange.Min
// is less than 100ms
dateTimeAxis.MinimalZoomConstrain = TimeSpan.FromMilliseconds(100);

Specifying Minimum Zoom Level on a CategoryDateTimeAxis

Specifying Minimum Zoom Level on a CategoryDateTimeAxis
Copy Code
var catAxis = new CategoryDateTimeAxis();
// Do not allow zooming where VisibleRange.Max-visibleRange.Min
// is less than 10 data-points
dateTimeAxis.MinimalZoomConstrain = 10

  

See Also